<?php

namespace yak\layui\models\rbac;

use yak\layui\models\Yak;
use Yii;

/**
 * This is the model class for table "{{%auth_item}}".
 *
 * @property string $name
 * @property int $type
 * @property string|null $description
 * @property string|null $rule_name
 * @property resource|null $data
 * @property int|null $created_at
 * @property int|null $updated_at
 *
 * @property AuthAssignment[] $authAssignments
 * @property AuthRule $ruleName
 * @property AuthItemChild[] $authItemChildren
 * @property AuthItemChild[] $authItemChildren0
 * @property AuthItem[] $children
 * @property AuthItem[] $parents
 */
class AuthItem extends Yak
{
    const TYPE_RULE = 1;
    const TYPE_PERMISSION = 2;

    /**
     * {@inheritdoc}
     */
    public static function tableName()
    {
        return '{{%auth_item}}';
    }

    /**
     * {@inheritdoc}
     */
    public function rules()
    {
        return [
            [['name', 'type'], 'required'],
            [['type'], 'integer'],
            [['description', 'data'], 'string'],
            [['name', 'rule_name'], 'string', 'max' => 64],
            [['name'], 'unique'],
            [['rule_name'], 'exist', 'skipOnError' => true, 'targetClass' => AuthRule::class, 'targetAttribute' => ['rule_name' => 'name']],
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function attributeLabels()
    {
        return [
            'name' => '名称',
            'type' => '类型',
            'description' => '描述',
            'rule_name' => '规则名称',
            'data' => '规则',
            'created_at' => '创建时间',
            'updated_at' => '更新时间',
        ];
    }

    public function typeLabels()
    {
        return [
            self::TYPE_RULE => '角色',
            self::TYPE_PERMISSION => '权限节点'
        ];
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getAuthAssignments()
    {
        return $this->hasMany(AuthAssignment::class, ['item_name' => 'name']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getRuleName()
    {
        return $this->hasOne(AuthRule::class, ['name' => 'rule_name']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getAuthItemChildren()
    {
        return $this->hasMany(AuthItemChild::class, ['parent' => 'name']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getAuthItemChildren0()
    {
        return $this->hasMany(AuthItemChild::class, ['child' => 'name']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getChildren()
    {
        return $this->hasMany(AuthItem::class, ['name' => 'child'])->viaTable('{{%auth_item_child}}', ['parent' => 'name']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getParents()
    {
        return $this->hasMany(AuthItem::class, ['name' => 'parent'])->viaTable('{{%auth_item_child}}', ['child' => 'name']);
    }

    public function save($runValidation = true, $attributeNames = null)
    {
        if ($this->validate()) {

            if ($this->type == self::TYPE_PERMISSION) {
                return $this->createPermission();
            }

            if ($this->type == self::TYPE_RULE) {
                return $this->createRole();
            }

        }
        return false;
    }

    protected function createPermission()
    {
        $auth = Yii::$app->authManager;
        $permission = $auth->createPermission(null);
        $permission->name = $this->name;
        $permission->description = $this->description;
        $permission->ruleName = $this->rule_name ?: null;
        $permission->data = $this->data ?: null;
        return $this->getIsNewRecord() ? $auth->add($permission) :
            $auth->update($this->name, $permission);
    }

    protected function createRole()
    {
        $auth = Yii::$app->authManager;
        $role = $auth->createRole(null);
        $role->name = $this->name;
        $role->description = $this->description;
        $role->ruleName = $this->rule_name ?: null;
        $role->data = $this->data ?: null;
        return $this->getIsNewRecord() ?  $auth->add($role) :
            $auth->update($this->name, $role);
    }
}
